package com.lakeworks.service.impl;

import com.lakeworks.common.constant.HttpStatus;
import com.lakeworks.common.domain.channel.ticket.BarcodeVo;
import com.lakeworks.common.domain.channel.ticket.TicketAdvance;
import com.lakeworks.common.domain.channel.ticket.TicketFactory;
import com.lakeworks.common.domain.ticket.*;
import com.lakeworks.common.enums.ticket.RouteKey;
import com.lakeworks.domain.SysChannel;
import com.lakeworks.domain.TktProcess;
import com.lakeworks.event.AdvanceTicketEvent;
import com.lakeworks.event.ReceiveTicketEvent;
import com.lakeworks.processor.AdvanceTicketProcessor;
import com.lakeworks.processor.ReceiveTicketProcessor;
import com.lakeworks.service.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static org.springframework.http.ResponseEntity.status;

/**
 * @Author: Auxps
 * @Date: 2023/3/9
 * Description:
 * 均需保证接口幂等
 * 三方渠道对接中  ThirdChannelException、RuntimeException 均已做异常处理
 * ThirdChannelException 渠道传入数据异常  响应状态状态码400 并返回errcode、errmsg
 * RuntimeException  内部异常 只响应状态码500
 */
@Slf4j
@Service
public class TicketChannelServiceImpl implements ITicketChannelService {


    @Autowired
    private ITktTicketService tktTicketService;

    @Autowired
    private ITktProcessService tktProcessService;

    @Autowired
    private ITktFlowService tktFlowService;

    @Autowired
    private ITktRouteService tktRouteService;

    @Autowired
    private IThirdChannelService thirdChannelService;

    @Autowired
    private ITktClaimsService tktClaimsService;

    @Autowired
    private ITktReclaimService tktReclaimService;


    ///////////////////////////////////

    @Autowired
    private ReceiveTicketProcessor receiveTicketProcessor;

    @Autowired
    private AdvanceTicketProcessor advanceTicketProcessor;


    private static final Logger log = LoggerFactory.getLogger(TicketChannelServiceImpl.class);




    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity addPlatform(TicketFactory ticketFactory) {
        log.info("打印请求参数--方法::addPlatform------param:[{}]",ticketFactory);
        TktFlow flow = tktFlowService.selectTktFlowByName(ticketFactory.getType());
        if (flow == null) {
            log.error("工单类型错误");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        TktRoute route = tktRouteService.selectTktRouteByIKey(ticketFactory.getEventType());
        if (route == null) {
            log.error("操作类型错误");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        ticketFactory.setChannelId(thirdChannelService.getSysChannel().getId());
        TktProcess process = receiveTicketProcessor.apply(new ReceiveTicketEvent(ticketFactory,route,"平台CE"));
        TktTicket ticket = process.getTicket();
        ticket.setFlowId(flow.getId());
        TktTicket tktTicket = tktTicketService.selectTktTicketBychannelId(ticket.getChannelId(),ticket.getChannelTicketId());
        if (tktTicket == null) {
            tktTicketService.insertTktTicket(ticket);
        }else {
            tktTicket.setStatus(ticket.getStatus());
            tktTicket.setNodeId(ticket.getNodeId());
            ticket.setId(tktTicket.getId());
            tktTicketService.updateTktTicket(tktTicket);
        }
        process.setTicketId(ticket.getId());
        process.setNodeId(route.getNodeId());
        tktProcessService.insertTktProcess(process);
        tktTicketService.addFile(ticket, process.getId());
        /*log.info("触发工单变化（创建工单）事件----orderNo:[{}]",ticket.getOrderNo());
        applicationContext.publishEvent(new TicketHoldingEvent(this,ticket.getOrderNo()));*/
        return status(HttpStatus.NO_CONTENT).build();
    }




   /* @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity addPlatform(TicketFactory ticketFactory) {
        log.info("打印请求参数--方法::addPlatform------param:[{}]",ticketFactory);
        TktFlow flow = tktFlowMapper.selectTktFlowByName(ticketFactory.getType());
        TktRoute route = new TktRoute();
        if (flow == null) {
            log.error("工单类型错误");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        if (ticketFactory.getType().equals(FlowType.URGENT_ORDER.name())){
            route = tktRouteMapper.selectTktRouteByIKey(RouteKey.URGENTORDER.name());
        } else {
            route = tktRouteMapper.selectTktRouteByIKey(ticketFactory.getEventType());
        }
        if (route == null) {
            log.error("操作类型错误");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        TktProcess process = receiveTicketProcessor.apply(new ReceiveTicketEvent(ticketFactory,route,"平台CE"));
        TktTicket ticket = process.getTicket();
        ticket.setFlowId(flow.getId());
        TktTicket tktTicket = tktTicketMapper.selectTktTicketBychannelId(ticket.getChannelTicketId());
        if (tktTicket == null) {
            tktTicketMapper.insertTktTicket(ticket);
        }else {
            tktTicket.setStatus(ticket.getStatus());
            tktTicket.setNodeId(ticket.getNodeId());
            ticket.setId(tktTicket.getId());
            tktTicketMapper.updateTktTicket(tktTicket) ;
        }
        process.setTicketId(ticket.getId());
        process.setNodeId(route.getNodeId());
        tktProcessMapper.insertTktProcess(process);
        tktTicketService.addFile(ticket, process.getId());
        log.info("触发工单变化（创建工单）事件----orderNo:[{}]",ticket.getOrderNo());
        applicationContext.publishEvent(new TicketHoldingEvent(this,ticket.getOrderNo()));
        return status(HttpStatus.NO_CONTENT).build();
    }*/

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity advanceTicket(TicketAdvance ticketAdvance) {
        log.info("打印请求参数--方法::advanceTicket------param:[{}]",ticketAdvance);
        ticketAdvance.setChannelId(thirdChannelService.getSysChannel().getId());
        TktTicket tktTicket;
        if(RouteKey.FACTORYHANDLE.name().equals(ticketAdvance.getEventType()) && ticketAdvance.getTktId() != null){
            tktTicket = tktTicketService.selectTktTicketById(ticketAdvance.getTktId());
        }else {
            tktTicket = tktTicketService.selectTktTicketBychannelId(ticketAdvance.getChannelId(),ticketAdvance.getTicketId());
        }
        if(tktTicket == null){
            log.error("工单id错误");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        TktRoute route = tktRouteService.selectTktRouteByIKey(ticketAdvance.getEventType());
        if(route == null){
            log.error("操作类型错误");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        tktTicket.setRemark(ticketAdvance.getComment());
        List<TktTicketFile> files = new ArrayList<>();
        if(!CollectionUtils.isEmpty(ticketAdvance.getVouchers())){
            ticketAdvance.getVouchers().forEach(f->{
                files.add(TktTicketFile.builder().fileUrl(f).fileType("img").remark(ticketAdvance.getComment()).build());
            });
        }
        tktTicket.setTktTicketFiles(files);
        TktProcess process = advanceTicketProcessor.apply(new AdvanceTicketEvent(tktTicket,ticketAdvance,route,"平台CE"));
        TktTicket ticket = process.getTicket();
        process.setTicketId(ticket.getId());
        process.setNodeId(route.getNodeId());
        tktProcessService.insertTktProcess(process);
        tktTicketService.addFile(ticket, process.getId());
        tktTicketService.runDecision(process.getDecisions(), process.getId().intValue());
        return status(HttpStatus.NO_CONTENT).build();
    }



    @Override
    public ResponseEntity addClaims(TktClaims tktClaims) {
        log.info("打印请求参数--方法::addClaims------param:[{}]",tktClaims);
        SysChannel sysChannel = thirdChannelService.getSysChannel();

        tktClaims.setCreateBy(sysChannel.getName());
        tktClaims.setModifyBy(sysChannel.getName());
        tktClaims.setChannelId(sysChannel.getId());
        int num = tktClaimsService.insertTktClaims(tktClaims);
        if(num == 0){
            log.info("下发赔偿单失败");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        return status(HttpStatus.CREATED).build();
    }

    @Override
    public ResponseEntity addRecalaim(TktReclaim tktReclaim) {
        log.info("打印请求参数--方法::addRecalaim------param:[{}]",tktReclaim);
        tktReclaim.setCreateBy(thirdChannelService.getSysChannel().getName());
        tktReclaim.setModifyBy(thirdChannelService.getSysChannel().getName());
        int num = tktReclaimService.insertTktReclaim(tktReclaim);
        if(num == 0){
            log.info("下发回收单失败");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        return status(HttpStatus.CREATED).build();
    }

    @Override
    public ResponseEntity updateClaims(TktClaims tktClaims) {
        log.info("打印请求参数--方法::updateClaims------param:[{}]",tktClaims);
        TktClaims claims = tktClaimsService.selectTktClaimsByChId(thirdChannelService.getSysChannel().getId(),tktClaims.getChClaimsId());
        if(claims == null){
            log.error("修改赔偿单错误");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        tktClaims.setId(claims.getId());
        int num = tktClaimsService.updateTktClaims(tktClaims);
        if(num == 0){
            log.info("修改赔偿单失败");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        return status(HttpStatus.NO_CONTENT).build();
    }

    @Override
    public ResponseEntity updateWashMode(List<BarcodeVo> barcodeVos) {
        log.info("打印请求参数--方法::updateWashMode------barcodeVos:[{}]",barcodeVos);
        if(CollectionUtils.isEmpty(barcodeVos)){
            log.info("水洗码列表为空");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        int num = tktTicketService.updateWashMode(barcodeVos);
        if(num == 0){
            log.info("修改洗涤方式失败");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        return status(HttpStatus.NO_CONTENT).build();
    }

    @Override
    public ResponseEntity arbitrament(TktClaimsRecord tktClaimsRecord) {
        log.info("打印请求参数--方法::arbitrament------tktClaimsRecord:[{}]",tktClaimsRecord);
        TktClaims claims = tktClaimsService.selectTktClaimsByChId(thirdChannelService.getSysChannel().getId(),tktClaimsRecord.getClaimsId());
        if(claims == null){
            log.error("赔偿单信息错误");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        tktClaimsRecord.setClaimsId(claims.getId());
        tktClaimsRecord.setType(1);
        tktClaimsRecord.setCreateBy(thirdChannelService.getSysChannel().getName());
        tktClaimsRecord.setModifyBy(thirdChannelService.getSysChannel().getName());
        int num = tktClaimsService.insertSelective(tktClaimsRecord);
        if(num == 0){
            log.info("裁决失败");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        TktClaims build = TktClaims.builder()
                .ftyAmount(tktClaimsRecord.getFtyAmount())
                .platformAmount(tktClaimsRecord.getPlatformAmount())
                .reconsiderStatus("END")
                .verdictComment(tktClaimsRecord.getComment())
                .verdictTime(LocalDateTime.now())
                .build();
        build.setId(claims.getId());
        int num1 = tktClaimsService.updateTktClaims(build);
        if(num1 == 0){
            log.info("修改金额失败");
            return status(HttpStatus.BAD_REQUEST).build();
        }
        return status(HttpStatus.NO_CONTENT).build();
    }




}
